package com.chatim.nonamechatim.common;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.FileCopyUtils;

import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Base64;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

public class JwtUtil {
    public static final Integer EXPIRE_TIME = 7 * 24 * 60 * 60;

    // 由于安全问题 jjwt 在 0.9.0以后版本要求秘钥必须为 256 位
    public static final String TOKEN_ISSUER = "Nt6KRnkSNs4MG5GCSeBptTnhwfRK2bTs8PEKAew9z5FGsFSzXkkDyaCMwax79HrQhFb6nFmb9k6JnfK0fQdaw5t1keNxm4mbrSjnn5BNdGk7apzH5GFskNjkHMsFfA2r";

    public static final String PrivateKey = "test";

    /**
     * 生成 JWT 字符串
     *
     */
    public static String createJWT() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        return Jwts.builder()
                //设置头部信息(相当于 JWT 字符串第一部分的内容)
                // .header().add("type", "JWT")
                // .and()
                //相当于 JWT 字符串第二部分的内容
                //签名密钥
                .signWith(SignatureAlgorithm.HS512, TOKEN_ISSUER)
                //设置过期时间
                .expiration(Date.from(java.time.Instant.now().plusSeconds(EXPIRE_TIME)))
                //设置用户名
                .subject(authentication.getName())
                //令牌签发时间
                // .issuedAt(new Date())
                .issuer(TOKEN_ISSUER) // 签发人
                .compact();
    }

    // 获取私钥
    public static PrivateKey getPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
            String key = new String(PrivateKey.getBytes(), StandardCharsets.UTF_8);
            byte[] privateKeyDecodedBytes = Base64.getDecoder().decode(key);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyDecodedBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            return keyFactory.generatePrivate(keySpec);
    }

    // 获取公钥
    public static RSAPublicKey getPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
        String key = new String(PrivateKey.getBytes(), StandardCharsets.UTF_8);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        byte[] publicKeyBase64Bytes = Base64.getDecoder().decode(key);
        X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBase64Bytes);
        PublicKey rsaPublicKey = keyFactory.generatePublic(publicKeySpec);
        return (RSAPublicKey) rsaPublicKey;
    }

    // 令牌校验
    public static Authentication verifyToken(String token) {
        try {
            // Claims claims = Jwts.parser()
            //         .verifyWith(getPublicKey()).build()
            //         .parseSignedClaims(token).getPayload();
            Claims claims = Jwts.parser().setSigningKey(TOKEN_ISSUER).build().parseSignedClaims(token).getPayload();
            String username = claims.getSubject();
            return UsernamePasswordAuthenticationToken.authenticated(username, null, null);
        } catch (Exception e) {
            //令牌校验失败
            return null;
        }

    }
}
